package com.runa.monitor.platinterface.netservice.equipment.furuisi;

import com.alibaba.fastjson.JSON;
import com.runa.monitor.comm.dto.Node;
import com.runa.monitor.comm.entity.CommNetEquipment;
import com.runa.monitor.comm.entity.CommNetService;
import com.runa.monitor.platinterface.backwork.function.TaskFunction;
import com.runa.monitor.platinterface.extend.equ.EquInstructService;
import com.runa.monitor.platinterface.netservice.client.ConcentratorClient;
import com.runa.monitor.platinterface.netservice.connect.commstatus.CommStatus;
import com.runa.monitor.platinterface.netservice.equipment.NetEqu;
import com.runa.monitor.platinterface.netservice.equipment.dtu.furuisi.FuRuiSiMessage;
import com.runa.monitor.platinterface.netservice.equipment.fail.BaseDriver;
import com.runa.monitor.platinterface.task.RequestTask;
import com.runa.persistence.task.RequestPendingTask;
import com.runa.persistence.util.LogUtil;
import com.runa.protocol.util.ByteUtil;
import com.runa.rccprotocol.dto.equdata.EquData;
import com.runa.rccprotocol.dto.furuisi.FuRuiSiRequestData;
import lombok.extern.slf4j.Slf4j;

import java.util.Collections;
import java.util.List;

/**
 * 2024/12/4 14:08
 * zhangYB
 */
@Slf4j
public class FuRuiSiClientDriver extends BaseDriver<String> {

    private ConcentratorClient client;
    private CommNetService commNetService;
    public static final String FRS_NAME = "furuisi";

    private FuRuiSiClientDriver(CommNetService commNetService) {
        super(commNetService.getName()+":"+FRS_NAME, 5000);
        this.client = getClient();
    }


    public static FuRuiSiClientDriver getInstance(CommNetService commNetService) {
        if (null == commNetService) {
            return null;
        }
        ConcentratorClient concentratorClient = ConcentratorClient.getInstance(commNetService);
        if (null == concentratorClient) {
            return null;
        }
        NetEqu netEqu = concentratorClient.getNetEqu();
        if (null == netEqu) {
            synchronized (FuRuiSiClientDriver.class) {
                netEqu = concentratorClient.getNetEqu();
                if (null == netEqu) {
                    netEqu = new FuRuiSiClientDriver(commNetService);
                    concentratorClient.setNetEqu(netEqu);
                }
            }
        }
        if (null != netEqu && netEqu instanceof FuRuiSiClientDriver) {
            return (FuRuiSiClientDriver)netEqu;
        }
        return null;
    }

    public static FuRuiSiClientDriver getInstance(CommNetEquipment commNetEquipment) {
        CommNetService commNetService = commNetEquipment.getCommNetService();
        return getInstance(commNetService);
//        FuRuiSiClientDriver driver = driverMap.get(commNetService.getId());
//        if (null == driver) {
//            synchronized (FuRuiSiClientDriver.class) {
//                if (null == driver) {
//                    driver = new FuRuiSiClientDriver(commNetEquipment);
//                    driverMap.put(commNetService.getId(), driver);
//                }
//            }
//        }
//        return driver;
    }

    private ConcentratorClient getClient() {
        if (null != this.commNetEquipment) {
            this.commNetService = this.commNetEquipment.getCommNetService();
            if (null != this.commNetService) {
                return ConcentratorClient.getInstance(this.commNetService);
            }
        }
        return null;
    }

    @Override
    public boolean online() {
        return null != this.client && this.client.isConnected();
    }

    @Override
    public void readNodeEqu(List<Node> nodeList, TaskFunction function, EquData.EquDataType type) {
        if (!online()) {
            function.doApply(CommStatus.OffLine, nodeList);
            return;
        }
        switch (type) {
            case VALVE:
            case PUBLIC_UNIT:
                readValve(nodeList, function);
                break;
        }
    }

    private void readValve(List<Node> nodeList, TaskFunction function) {
        for (Node node : nodeList) {
            FuRuiSiRequestData requestData = new FuRuiSiRequestData(node.getSerial());
            requestData.readValve(node.getSerial(), node.getIndex());
            requestData.setRemain(Collections.singletonList(node));
            sendRequest(requestData, function);
        }
    }

    @Override
    public void valveOnOffControl(List<Node> nodeList, boolean ifLock, Integer opening, TaskFunction function) {
        if (!online()) {
            function.doApply(CommStatus.OffLine, nodeList);
            return;
        }
        for (Node node : nodeList) {
            FuRuiSiRequestData requestData = new FuRuiSiRequestData(node.getSerial());
            requestData.setValveOpen(node.getSerial(), node.getIndex(), opening);
            requestData.setRemain(Collections.singletonList(node));
            sendRequest(requestData, function);
        }

    }

    @Override
    public void send(RequestTask requestTask) {
        try {
            if (online()) {
                log.info("集中器——{} 发送指令: {}", serial(), ByteUtil.byteToHexString(requestTask.getRequestData().getData()));
                RequestPendingTask.addTask(serial(), requestTask.getTask());
                client.getChannel().writeAndFlush(requestTask.getRequestData()).sync();
                this.lastTime = System.currentTimeMillis();
                sending = requestTask.getRequestData().isHaveResult();
                LogUtil.info(serial(), requestTask.getRequestData().getData(), "发送");
                EquInstructService.start(serial(), requestTask.getRequestData());
            } else {
                requestTask.getTaskFunction().doApply(CommStatus.OffLine, requestTask.getRequestData().getRemain());
            }
        } catch (Exception e) {
            log.error("NetEqu.send: ", e);
        }
    }

    public void receiveMsg(FuRuiSiMessage msg) {
        System.out.println(JSON.toJSONString(msg));

    }


}

